﻿using FMS.Core.Database;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FMS.DataAccess.Repository
{
    public abstract class RepositoryBase<T> : IRepository<T> where T : class
    {

        public DbContext Context { get; set; }

        private readonly IDbSet<T> dbSet;

        public RepositoryBase(DbContext context)
        {
            this.Context = context;
            this.dbSet = context.Set<T>();
        }

        public void Add(T entity)
        {
            this.dbSet.Add(entity);
        }

        public void Update(T entity)
        {
            var entry = this.Context.Entry(entity);
            this.dbSet.Attach(entity);
            entry.State = System.Data.EntityState.Modified;
        }

        public void Delete(T entity)
        {
            this.dbSet.Remove(entity);
        }

        public void Copy(T source, T target)
        {
            throw new NotImplementedException();
        }

        public void Flush()
        {
            throw new NotImplementedException();
        }

        public T Get(int id)
        {
            return this.dbSet.Find(id);
        }

        public T Get(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            return this.dbSet.FirstOrDefault(predicate);
        }

        public IQueryable<T> Table
        {
            get { return this.dbSet; } 
        }

        public int Count(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            return this.dbSet.Count(predicate);
        }

        public IEnumerable<T> Fetch(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            return this.dbSet.Where(predicate).ToList();
        }

        public IEnumerable<T> Fetch(System.Linq.Expressions.Expression<Func<T, bool>> predicate, int skip, int count)
        {
            return this.dbSet.Where(predicate).Skip(skip).Take(count);
        }

        public void Delete(int id)
        {
            var item = this.dbSet.Find(id);
            this.dbSet.Remove(item);
        }
    }
}
